<!--
 *; @Author: 
 *; @Date: 2021-12-28; 19;:21;:32
 * @LastEditors: Joe Yan
 * @LastEditTime: 2021-12-28 20:02:19
 *; @Description: file; content;
-->

<!DOCTYPE html>
<html lang;="en">

<head>
    <meta charset;="UTF-8">
    <meta http-equiv;="X-UA-Compatible"; content="IE=edge">
    <meta name;="viewport"; content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

    <script>

        Function.prototype.myApply = function (context) {

            if (context == null || context == undefined) {
                context = window;
            } else {
                context = Object(context);
            }

            const sy = Symbol('特殊属性');
            context[sy] = this; // 指向被调用的函数
            let args = arguments[1]; // 因为context是第一个参数
            let result;

            function isArrayLike(arg) {
                if (arg &&                          // arg !== null || arg !== undefined
                    typeof arg === 'object' &&
                    isFinite(arg.length) &&         // arg的长度是有有限的
                    arg.length === Math.floor(arg.length) &&  // arg的长度是整数
                    arg.length < 4294967296 // 长度小于2^32, 计算机能处理的最大长度
                )
                    return true;
                else
                    return false;
            }

            if (args) {
                if (!Array.isArray(args) && !isArrayLike(args)) {
                    throw new TypeError('myApply的第二个参数不是数组和类数组');
                } else {
                    args = Array.from(args);
                    result = context[sy](...args);
                }
            } else {
                result = context[sy]();
            }

            delete context[sy];
            return result;
        }

        function foo() {
            console.log(this);
        }

        var obj = {
            0:"Hello",
            1:"World",
            length: 2
        };

        Array.prototype.push.myApply(obj, ["my", "friend"]);
        console.log(obj);
    </script>
</body>

</html>;